package cn.dcpnet.feign;

import cn.dcpnet.annotation.DFeign;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import javax.annotation.Resource;
import java.util.Set;

/**
 * <h1>类名称</h1>
 *
 * <p>
 * 类描述
 * </p>
 *
 * @author Dcpnet
 * @since 2025/1/2 22:46
 **/
public class DFeignBeanRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {

    private Environment environment;

    /**
     * Register bean definitions as necessary based on the given annotation metadata of
     * the importing {@code @Configuration} class.
     * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
     * registered here, due to lifecycle constraints related to {@code @Configuration}
     * class processing.
     * <p>The default implementation is empty.
     *
     * @param importingClassMetadata annotation metadata of the importing class
     * @param registry               current bean definition registry
     */
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        DFeignScanner scanner = new DFeignScanner(registry);
        scanner.addIncludeFilter(new AnnotationTypeFilter(DFeign.class));
        ImportBeanDefinitionRegistrar.super.registerBeanDefinitions(importingClassMetadata, registry);

        String feignPackage = environment.getProperty("feign.package");
        Set<BeanDefinition> definitions = scanner.findCandidateComponents(feignPackage);
        for (BeanDefinition definition : definitions) {
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(DFeignFactoryBean.class);
            builder.addConstructorArgValue(definition.getBeanClassName());
            AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
            registry.registerBeanDefinition(definition.getBeanClassName(), beanDefinition);
        }

    }

    /**
     * Set the {@code Environment} that this component runs in.
     *
     * @param environment
     */
    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}
